#include <am.h>
#include <nemu.h>

#define SYNC_ADDR (VGACTL_ADDR + 4)
static int width=0,height=0;
void __am_gpu_init()
{
  uint32_t data = inl(VGACTL_ADDR);
  width= data >> 16;
  height = data & 0xffff;
}

void __am_gpu_config(AM_GPU_CONFIG_T *cfg)
{
  uint32_t data = inl(VGACTL_ADDR);
  *cfg = (AM_GPU_CONFIG_T){
      .present = true, .has_accel = false, .width = data >> 16, .height = data & 0xffff, .vmemsz = (data >> 16) * (data & 0xffff) * sizeof(uint32_t)};
}

void __am_gpu_fbdraw(AM_GPU_FBDRAW_T *ctl)
{
  // uint32_t *pixels = (uint32_t *)ctl->pixels;
  // uint32_t *fb = (uint32_t *)FB_ADDR;
  // const int w = ctl->w, h = ctl->h,x=ctl->x,y=ctl->y;
  // for (int j = 0; j < h; j++)
  // {
  //   for (int i = 0; i < w; i++)
  //   {
  //     fb[(y + j) * width + (x + i)] = pixels[j * w + i];
  //   }
  // }
  const int w = ctl->w, h = ctl->h;
  uint32_t *fb = (uint32_t *)FB_ADDR + ctl->x + ctl->y * width;
  uint32_t *pixels = (uint32_t *)ctl->pixels;
  for (int j = 0; j < h; j++)
  {
    //uint32_t *ft=fb;
    for (int i = 0; i < w; i++)
    {
      fb[i] = *pixels++;
    }
    fb+=width;
  }

  if (ctl->sync)
  {
    outl(SYNC_ADDR, 1);
  }
}

void __am_gpu_status(AM_GPU_STATUS_T *status)
{
  status->ready = true;
}
